package tr.edu.ege.cs.egenav.demo2;


import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import tr.edu.ege.cs.egenav.direction.Junction;
import tr.edu.ege.cs.egenav.direction.MapColorModel;
import tr.edu.ege.cs.egenav.direction.Path;
import tr.edu.ege.cs.egenav.direction.RasterPathFinder;
import tr.edu.ege.cs.egenav.direction.Threshold;
import tr.edu.ege.cs.egenav.direction.TurningPoint;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * DemoApplication2_V1_1.java
 *
 * Created on 09.Oca.2015, 16:34:11
 */
/**
 *
 * @author Özgün Yılmaz
 */
public class DemoApplication2_V1_1 extends javax.swing.JFrame {

    Junction selJunction=null;
    TurningPoint selTP=null;
    /** Creates new form DemoApplication2_V1_1 */
    public DemoApplication2_V1_1() {
        initComponents();
        tblJunction.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
            @Override
            public void valueChanged(ListSelectionEvent event) {

                //below selected junction is highlighted by painting a square
                if (tblJunction.getModel().getRowCount()>0 && tblJunction.getSelectedRow()>-1){
                    selJunction=new Junction((String)tblJunction.getValueAt(tblJunction.getSelectedRow(), 0), (String)tblJunction.getValueAt(tblJunction.getSelectedRow(), 1));
                    repaint();
                }

            }
        });
        tblTp.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
            @Override
            public void valueChanged(ListSelectionEvent event) {

                //below selected turning point is highlighted by painting a square
                if (tblTp.getModel().getRowCount()>0 && tblTp.getSelectedRow()>-1){
                    selTP=new TurningPoint((String)tblTp.getValueAt(tblTp.getSelectedRow(), 0), ((Long)tblTp.getValueAt(tblTp.getSelectedRow(), 1)).toString());
                    repaint();
                }
                
            }
        });
        if (cmbFile.getModel().getSize()>0){
            imgPanel.setToolTipText("Choose 2 points (origin and destination) by clicking on the pathways (white colored area) of the image");
        }

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jPanel2 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        tblJunction = new javax.swing.JTable(){
            public boolean isCellEditable(int row, int column)
            {
                return false;
            }
            public String getToolTipText(MouseEvent e) {
                Point p = e.getPoint();
                int row = rowAtPoint(p);
                int col = columnAtPoint(p);

                //table.setToolTipText(String.valueOf(table.getValue(row,column)));

                if (-1 < row) {

                    return /*"<html><font color=\"blue\">"+*/getValueAt(row, col).toString()/*+"</font></html>"*/;

                } else {
                    return null;
                }
            }

            protected JTableHeader createDefaultTableHeader() {
                return new JTableHeader(columnModel) {
                    public String getToolTipText(MouseEvent e) {
                        String tip = null;
                        java.awt.Point p = e.getPoint();
                        int index = columnModel.getColumnIndexAtX(p.x);
                        //int realIndex = columnModel.getColumn(index).getModelIndex();
                        if (index==0){
                            return "x-y coordinates of the junction point";
                        }else{
                            return "Available directions relative to the heading direction (Angles in degrees)";
                        }
                        //return columnModel.getColumn(index).getHeaderValue().toString();
                    }
                };
            }
        };
        jPanel4 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        tblTp = new javax.swing.JTable(){
            public boolean isCellEditable(int row, int column)
            {
                return false;
            }
            public String getToolTipText(MouseEvent e) {
                Point p = e.getPoint();
                int row = rowAtPoint(p);
                int col = columnAtPoint(p);

                //table.setToolTipText(String.valueOf(table.getValue(row,column)));

                if (-1 < row) {
                    return /*"<html><font color=\"blue\">"+*/getValueAt(row, col).toString()/*+"</font></html>"*/;
                }else {
                    return null;
                }
            }
            protected JTableHeader createDefaultTableHeader() {
                return new JTableHeader(columnModel) {
                    public String getToolTipText(MouseEvent e) {
                        String tip = null;
                        java.awt.Point p = e.getPoint();
                        int index = columnModel.getColumnIndexAtX(p.x);
                        //int realIndex = columnModel.getColumn(index).getModelIndex();
                        //return columnModel.getColumn(index).getHeaderValue().toString();
                        if (index==0){
                            return "x-y coordinates of the turning point";
                        }else if (index==1){
                            return "Turning angle relative to the heading direction (Angle in degrees)";
                        }else{
                            return "Textual instructions";
                        }
                    }
                };
            }
        };
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        lblOrigin = new javax.swing.JLabel();
        lblDest = new javax.swing.JLabel();
        lblHT = new javax.swing.JLabel();
        lblVT = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jPanel5 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        File f = new File("images\\");
            if (!f.exists()){
                JOptionPane.showMessageDialog(null, ".\\images directory not found\nCreate 'images' directory on the local path and add some map images there", "Error", JOptionPane.ERROR_MESSAGE);
            }
            cmbFile = new javax.swing.JComboBox(f.list(new FilenameFilter() {

                @Override
                public boolean accept(File dir, String name) {
                    if (name.length() < 4) {
                        return false;
                    }
                    String suf = name.substring(name.length() - 4);
                    if (suf.equalsIgnoreCase(".png") || suf.equalsIgnoreCase(".jpg") || suf.equalsIgnoreCase(".bmp") || suf.equalsIgnoreCase(".gif")) {
                        return true;
                    } else {
                        return false;
                    }
                }
            })
        );
        jLabel2 = new javax.swing.JLabel();
        lblPos = new javax.swing.JLabel();
        imgPanel = new ImagePanel("images\\" + (String) cmbFile.getSelectedItem());

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setTitle("Pathfinder");

            jSplitPane1.setDividerLocation(350);
            jSplitPane1.setLastDividerLocation(350);

            jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Info"));
            jPanel2.setPreferredSize(new java.awt.Dimension(324, 500));

            jLabel3.setText("Origin (x,y):");

            jLabel4.setText("Destination (x,y):");

            jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Junctions"));
            jPanel3.setPreferredSize(new java.awt.Dimension(330, 165));

            tblJunction.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {

                },
                new String [] {
                    "Point (x, y)", "Available directions (angles in degrees)"
                }
            ) {
                Class[] types = new Class [] {
                    java.lang.String.class, java.lang.String.class
                };
                boolean[] canEdit = new boolean [] {
                    false, false
                };

                public Class getColumnClass(int columnIndex) {
                    return types [columnIndex];
                }

                public boolean isCellEditable(int rowIndex, int columnIndex) {
                    return canEdit [columnIndex];
                }
            });
            tblJunction.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
            jScrollPane3.setViewportView(tblJunction);
            tblJunction.getColumnModel().getColumn(0).setPreferredWidth(80);
            tblJunction.getColumnModel().getColumn(1).setPreferredWidth(300);

            javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
            jPanel3.setLayout(jPanel3Layout);
            jPanel3Layout.setHorizontalGroup(
                jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 323, Short.MAX_VALUE)
            );
            jPanel3Layout.setVerticalGroup(
                jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 157, Short.MAX_VALUE)
            );

            jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Turning Points"));
            jPanel4.setPreferredSize(new java.awt.Dimension(330, 165));

            tblTp.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {

                },
                new String [] {
                    "Point (x, y)", "Turning angle (degrees)", "Instructions"
                }
            ) {
                Class[] types = new Class [] {
                    java.lang.String.class, java.lang.String.class, java.lang.String.class
                };
                boolean[] canEdit = new boolean [] {
                    false, false, false
                };

                public Class getColumnClass(int columnIndex) {
                    return types [columnIndex];
                }

                public boolean isCellEditable(int rowIndex, int columnIndex) {
                    return canEdit [columnIndex];
                }
            });
            jScrollPane4.setViewportView(tblTp);
            tblTp.getColumnModel().getColumn(0).setPreferredWidth(80);
            tblTp.getColumnModel().getColumn(1).setPreferredWidth(80);
            tblTp.getColumnModel().getColumn(2).setPreferredWidth(300);

            javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
            jPanel4.setLayout(jPanel4Layout);
            jPanel4Layout.setHorizontalGroup(
                jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 323, Short.MAX_VALUE)
            );
            jPanel4Layout.setVerticalGroup(
                jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 157, Short.MAX_VALUE)
            );

            jLabel8.setText("Vertical threshold (px):");

            jLabel9.setText("Horizontal threshold (px):");

            lblOrigin.setBackground(java.awt.Color.white);
            lblOrigin.setText(" ");
            lblOrigin.setBorder(javax.swing.BorderFactory.createEtchedBorder());
            lblOrigin.setOpaque(true);

            lblDest.setBackground(java.awt.Color.white);
            lblDest.setText(" ");
            lblDest.setBorder(javax.swing.BorderFactory.createEtchedBorder());
            lblDest.setOpaque(true);

            lblHT.setBackground(java.awt.Color.white);
            lblHT.setText(" ");
            lblHT.setBorder(javax.swing.BorderFactory.createEtchedBorder());
            lblHT.setOpaque(true);

            lblVT.setBackground(java.awt.Color.white);
            lblVT.setText(" ");
            lblVT.setBorder(javax.swing.BorderFactory.createEtchedBorder());
            lblVT.setOpaque(true);

            javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
            jPanel2.setLayout(jPanel2Layout);
            jPanel2Layout.setHorizontalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jLabel8)
                        .addComponent(jLabel9)
                        .addComponent(jLabel4)
                        .addComponent(jLabel3))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(lblDest, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(lblOrigin, javax.swing.GroupLayout.DEFAULT_SIZE, 153, Short.MAX_VALUE)
                        .addComponent(lblVT, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(lblHT, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
                .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
            );
            jPanel2Layout.setVerticalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel3)
                        .addComponent(lblOrigin, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel4)
                        .addComponent(lblDest, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel9)
                        .addComponent(lblHT, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel8)
                        .addComponent(lblVT, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGap(18, 18, 18)
                    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE))
            );

            jScrollPane1.setViewportView(jPanel2);

            jSplitPane1.setLeftComponent(jScrollPane1);

            jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Image"));

            jLabel1.setText("Image file:");

            cmbFile.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmbFileActionPerformed(evt);
                }
            });

            jLabel2.setText("Mouse position (x,y):");

            lblPos.setBackground(java.awt.Color.white);
            lblPos.setBorder(javax.swing.BorderFactory.createEtchedBorder());
            lblPos.setOpaque(true);
            lblPos.setPreferredSize(new java.awt.Dimension(40, 18));

            javax.swing.GroupLayout imgPanelLayout = new javax.swing.GroupLayout(imgPanel);
            imgPanel.setLayout(imgPanelLayout);
            imgPanelLayout.setHorizontalGroup(
                imgPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 545, Short.MAX_VALUE)
            );
            imgPanelLayout.setVerticalGroup(
                imgPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 490, Short.MAX_VALUE)
            );

            javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
            jPanel5.setLayout(jPanel5Layout);
            jPanel5Layout.setHorizontalGroup(
                jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel5Layout.createSequentialGroup()
                    .addComponent(jLabel1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(cmbFile, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(18, 18, 18)
                    .addComponent(jLabel2)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(lblPos, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addComponent(imgPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            );
            jPanel5Layout.setVerticalGroup(
                jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel5Layout.createSequentialGroup()
                    .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(cmbFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel2))
                        .addComponent(lblPos, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(imgPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            );

            jScrollPane2.setViewportView(jPanel5);

            jSplitPane1.setRightComponent(jScrollPane2);

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 921, Short.MAX_VALUE)
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 560, Short.MAX_VALUE)
            );

            pack();
        }// </editor-fold>//GEN-END:initComponents

    private void cmbFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmbFileActionPerformed
        //When the user selects an image from the combobox, stored image in the panel is updated
        imgPanel.setImg("images\\" +(String) cmbFile.getSelectedItem());
        imgPanel.revalidate();  //imgPanel is revalidated because width and height of the new image might be larger. So the panel's size must be changed.
        imgPanel.repaint();     //shows new image
        clearText();            //labels and the tables are cleared
        imgPanel.reset();       //click count in the imgPanel is set to zero
        selJunction=null;       //selected junction is nullified
        selTP=null;             //selected turning point is nullified
        pack();
    }//GEN-LAST:event_cmbFileActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new DemoApplication2_V1_1().setVisible(true);
            }
        });
    }

    public void clearText(){

        lblOrigin.setText(" ");
        lblDest.setText(" ");
        lblHT.setText(" ");
        lblVT.setText(" ");
        DefaultTableModel dm = (DefaultTableModel) tblJunction.getModel();
        int rowCount = dm.getRowCount();
        //Remove rows one by one from the end of the table
        for (int i = rowCount - 1; i >= 0; i--) {
            dm.removeRow(i);
        }

        dm = (DefaultTableModel) tblTp.getModel();
        rowCount = dm.getRowCount();
        //Remove rows one by one from the end of the table
        for (int i = rowCount - 1; i >= 0; i--) {
            dm.removeRow(i);
        }
        
    }

    class ImagePanel extends JPanel {
        
        //This is a custom drawing panel to display map images

        BufferedImage img, img2;
        String path;
        InputStream in;
        int x, y, renk;
        int click = 0; //stores click count
        JLabel pos;

        public void reset() {
            click = 0;
        }

        public final void setImg(String s) {
            //In this method, image denoted by s is read and assigned to img, img2
            path=s;
            try {
                //img are img2 are identical. img used for scratch during path finding. After path finding process because it is modified it is discarded.
                img = ImageIO.read(new File(s));
                img2 = ImageIO.read(new File(s));

            } catch (IOException ex) {
                System.out.println(ex.toString());
            }

        }

        @Override
        public void paint(Graphics g) {

            g.drawImage(img2, 0, 0, null); //The original image, which is img2, is painted in the panel

            if (selJunction!=null){
                //If a junction is selected from the table, that junction point is emphasized to the user by painting a blue circle on the image
                paintPoint(g, selJunction.getPoint(), Color.BLUE);
            }
            if (selTP!=null){
                //If a turning point is selected from the table, that turning point is emphasized to the user by painting a green circle on the image
                paintPoint(g, selTP.getPoint(), Color.GREEN);
            }

        }
        
        public void paintPoint(Graphics g, Point p, Color c) {
            //This method is used to show junction turning points to the user by painting a circle on the given point in given color
            float alpha = 0.70f;
            int type = AlphaComposite.SRC_OVER;
            AlphaComposite composite =  AlphaComposite.getInstance(type, alpha);
            Graphics2D g2d=(Graphics2D)g;
            g2d.setColor(c);
            g2d.setComposite(composite);
            RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHints(rh);
            g2d.fillOval(p.x-10, p.y-10, 20, 20);
        }

        public ImagePanel() {

        }

        public ImagePanel(String s) {

            setImg(s);
            setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));

            addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mouseExited(java.awt.event.MouseEvent evt) {
                    formMouseExited(evt);
                }
            });
            addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
                @Override
                public void mouseMoved(java.awt.event.MouseEvent evt) {
                    formMouseMoved(evt);
                }
            });

            addMouseListener(
                new MouseAdapter() {  // anonymous inner class

                    Point p1, p2;
                    // handle mouse click event
                    @Override
                    public void mouseClicked(MouseEvent event) {


                        x = event.getX();
                        y = event.getY();

                        renk = img2.getRGB(x, y);
                        if (renk == Color.BLACK.getRGB()) {
                            //if clicked pixel's color is black a warning message is showed and returned from the method
                            JOptionPane.showMessageDialog(null, "You should click on the pathways (white colored area)", "Clicked point not a pathway", JOptionPane.WARNING_MESSAGE);
                            return;
                        }

                        click++;    //increment click count
                        if (click == 1) {           //If it is the first click
                            p1 = new Point(x, y);   //create p1
                            clearText();            //clear any info shown
                            lblOrigin.setText(x+", "+y);    //set origin label to show x and y values


                        } else {    //If it is not first click which means it is second click because at this point click can only hold 1 or 2
                            selJunction=null;   //Selected junction and turning point are nullified because all of these points will be recalculated.
                            selTP=null;
                            p2 = new Point(x, y);   //create p2
                            lblDest.setText(x+", "+y); //set destination label to show x and y values

                            setImg(path);   //reassign img and img2

                            MapColorModel mcm=new MapColorModel();  //create a new MapColorModel object
                            mcm.addBorderColor(Color.BLACK);        //add a border (non-pathway) color
                            mcm.addTrackColor(Color.WHITE);         //add a track (pathway) color
                            mcm.setBorderBased(true);               //determine whether mcm will be border based or track based
                            //MapColorModel class is used to store border and track colors. 
                            //There can be many border or track colors. But at least there must be one color specified as a border or track color.
                            //This class helps decide whether to continue or stop while scanning the image.
                            //If it is border based, scanning continues until a border colored pixel is processed.
                            //If it is track based, scanning continues while the processed pixel is track colored.
                            //This results in flexibility
                            //It is sufficient to provide colors for only one category (border or track).
                            //In this application it doesn't matter whether it is border or track based because there is one color for border and track each.


                            Path path = RasterPathFinder.findPath(img, p1, p2, mcm);
                            //A path is found (if there is any) using RasterPathFinder class's static method findPath
//path.drawLinePath(img2);
                            Threshold x=path.getThreshold(img2, mcm); //threshold value  is auto-detected. It is also possible to manually specify threshold values.
                            
                            Path pts2=path.toNormalizedLine(img2,mcm,x); //path is converted to a normalized (simplified) line 
//pts2.drawLinePath(img2);
                            pts2.centerPath(img2, mcm, x);  //path is centered
//pts2.drawLinePath(img2);
                            lblHT.setText(Integer.toString(x.getHorizontal()));  //auto-detected threshold values are shown
                            lblVT.setText(Integer.toString(x.getVertical()));

                            ArrayList<Junction> jnc=pts2.findJunctions(img2, mcm, x); //junctions are retrieved
                            //Junction info are added to the junction table
                            for (int i=0;i<jnc.size();i++){
                                Junction j=jnc.get(i);
                                Object[] obj={j.getPoint().x+", "+j.getPoint().y, j.toString2()};

                                ((DefaultTableModel)tblJunction.getModel()).addRow(obj);
                            }
                            //Turning point info are added to the turning point table
                            ArrayList<TurningPoint> tp=pts2.getTurningPoints(25);
                            for (int i=0;i<tp.size();i++){

                                TurningPoint tpn=tp.get(i);
                                Object[] obj={tpn.getPoint().x+", "+tpn.getPoint().y, Math.round(tpn.getTurningAngle()), tpn.getInstructions()};

                                ((DefaultTableModel)tblTp.getModel()).addRow(obj);
                            }

                            pts2.drawLinePath(img2); //path is drawn on the image
                            click=0;    //zero is assigned to click.

                        }

                        repaint();  //repaint image
                    }
                }); // end call to addMouseListener



        }

        private void formMouseMoved(java.awt.event.MouseEvent evt) {
            //Mouse move event: x and y coordinates of the cursor pozition are updated
            lblPos.setText(evt.getX()+", "+evt.getY());
        }

        private void formMouseExited(java.awt.event.MouseEvent evt) {
            //Mouse exitted event: lblPos is set to empty string when the mouse exits the panel
            lblPos.setText("");
        }

        @Override
        public Dimension getPreferredSize() {
            if (img == null) {
                return new Dimension(545, 490);  //Deafult height and width of the panel if img==null
            } else {
                //If img is not null, height and width of the panel are set to image's dimension.
                return new Dimension(img.getWidth(null), img.getHeight(null));  
            }
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox cmbFile;
    private ImagePanel imgPanel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JLabel lblDest;
    private javax.swing.JLabel lblHT;
    private javax.swing.JLabel lblOrigin;
    private javax.swing.JLabel lblPos;
    private javax.swing.JLabel lblVT;
    private javax.swing.JTable tblJunction;
    private javax.swing.JTable tblTp;
    // End of variables declaration//GEN-END:variables
}
